ADDI = 'addi'
SUBI = 'subi'
XORI = 'xori'
ORI  = 'ori'
ANDI = 'andi'

ADD  = 'add'
SUB  = 'sub'
XOR  = 'xor'
OR   = 'OR'
AND  = 'and'

SW   = 'sw'
BEQ  = 'beq'
BNE  = 'bne'
BLT  = 'blt'
BGE  = 'bge'
BLTU = 'bltu'
BGEU = 'bgeu'

JAL  = 'jal'
LUI  = 'lui'

LW   = 'lw'

ITYPE_OPCODE = 0b000_0001
RTYPE_OPCODE = 0b000_0010
STYPE_OPCODE = 0b000_0011
BTYPE_OPCODE = 0b000_0100
JTYPE_OPCODE = 0b000_0101
UTYPE_OPCODE = 0b000_0110
LW_OPCODE = 0b000_0111

opcode_dict = {
    ADDI : ITYPE_OPCODE,
    SUBI : ITYPE_OPCODE,
    XORI : ITYPE_OPCODE,
    ORI  : ITYPE_OPCODE,
    ANDI : ITYPE_OPCODE,
    
    ADD  : RTYPE_OPCODE,
    SUB  : RTYPE_OPCODE,
    XOR  : RTYPE_OPCODE,
    OR   : RTYPE_OPCODE,
    AND  : RTYPE_OPCODE,

    SW   : STYPE_OPCODE,

    BEQ  : BTYPE_OPCODE,
    BNE  : BTYPE_OPCODE,
    BLT  : BTYPE_OPCODE,
    BGE  : BTYPE_OPCODE,
    BLTU : BTYPE_OPCODE,
    BGEU : BTYPE_OPCODE,

    JAL  : JTYPE_OPCODE,

    LUI  : UTYPE_OPCODE,

    LW   : LW_OPCODE,
}

ALU_ADD = 0b000
ALU_SUB = 0b001
ALU_XOR = 0b010
ALU_OR  = 0b011
ALU_AND = 0b100

alu_opcode_dict = {
    ADD  : ALU_ADD,
    ADDI : ALU_ADD,
    SUBI : ALU_SUB,
    SUB  : ALU_SUB,
    XORI : ALU_XOR,
    XOR  : ALU_XOR,
    ORI  : ALU_OR,
    OR   : ALU_OR,
    ANDI : ALU_AND,
    AND : ALU_AND,
}

CMP_EQ  = 0b000
CMP_NE  = 0b001
CMP_LT  = 0b010
CMP_GE  = 0b011
CMP_LTU = 0b100
CMP_GEU = 0b101

cmp_opcode_dict = {
    BEQ  : CMP_EQ,
    BNE  : CMP_NE,
    BLT  : CMP_LT,
    BGE  : CMP_GE,
    BLTU : CMP_LTU,
    BGEU : CMP_GEU,
}